// +----------------------------------------------------------------------
// | JavaWeb_EleVue_Pro前后端分离旗舰版框架 [ JavaWeb ]
// +----------------------------------------------------------------------
// | 版权所有 2021 上海JavaWeb研发中心
// +----------------------------------------------------------------------
// | 官方网站: http://www.javaweb.vip/
// +----------------------------------------------------------------------
// | 作者: 鲲鹏 <javaweb520@gmail.com>
// +----------------------------------------------------------------------
// | 免责声明:
// | 本软件框架禁止任何单位和个人用于任何违法、侵害他人合法利益等恶意的行为，禁止用于任何违
// | 反我国法律法规的一切平台研发，任何单位和个人使用本软件框架用于产品研发而产生的任何意外
// | 、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、附带
// | 或衍生的损失等)，本团队不承担任何法律责任。本软件框架只能用于公司和个人内部的法律所允
// | 许的合法合规的软件产品研发，详细声明内容请阅读《框架免责声明》附件；
// +----------------------------------------------------------------------

package com.javaweb.admin.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.XmlUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.JsonObject;
import com.javaweb.admin.entity.*;
import com.javaweb.admin.mapper.*;
import com.javaweb.admin.service.INcServiceLogService;
import com.javaweb.admin.vo.kdlgm.KdlGMVo;
import com.javaweb.common.config.CommonConfig;
import com.javaweb.common.config.DataSourceType;
import com.javaweb.common.config.DynamicDataSource;
import com.javaweb.common.config.SpecifyDataSource;
import com.javaweb.common.common.BaseQuery;
import com.javaweb.common.common.BaseServiceImpl;
import com.javaweb.admin.query.KdlGMQuery;
import com.javaweb.admin.service.IKdlGMService;
import com.javaweb.common.utils.CommonUtils;
import com.javaweb.common.utils.DateUtils;
import com.javaweb.common.utils.StringUtils;
import com.javaweb.admin.vo.kdlotherinout.KdlOtherInoutInfoVo;
import com.javaweb.admin.vo.kdlotherinout.KdlOtherInoutListVo;
import com.javaweb.common.utils.JsonResult;
import com.javaweb.system.constant.Constants;
import com.seegw.shaphar.DDKJConfig;
import com.seegw.shaphar.KDLConfig;
import com.seegw.shaphar.KDLRequest;
import com.sphsine.bip.SHYPConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

/**
  * <p>
  * 其他出入库 服务类实现
  * </p>
  *
  * @author 鲲鹏
  * @since 2024-01-27
  */
@Service
public class KdlGMServiceImpl extends BaseServiceImpl<KdlGMMapper, KdlGM> implements IKdlGMService {

    @Autowired
    private KdlGMMapper kdlGMMapper;

    @Autowired
    private KdlQffFeedbackMapper kdlQffFeedbackMapper;

    @Autowired
    INcServiceLogService ncServiceLogService;

    @Autowired
    NcOnhandMapper ncOnhandMapper;

    @Autowired
     private KdlZ05kdlMapper z05kdlMapper;

    @Autowired
    private KdlZ05kdlBMapper z05kdlBMapper;


    @Autowired
    private KdlInspectionresultStatusMapper kdlInspectionresultStatusMapper;


    /**
     * 获取数据列表
     *
     * @param query 查询条件
     * @return
     */
    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult getList(BaseQuery query) {
        KdlGMQuery kdlOtherInoutQuery = (KdlGMQuery) query;
        // 查询条件
        QueryWrapper<KdlGM> queryWrapper = new QueryWrapper<>();

        // queryWrapper.orderByDesc("id");

        // 获取数据列表
        IPage<KdlGMVo> page = new Page<>(kdlOtherInoutQuery.getPage(), kdlOtherInoutQuery.getLimit());
        IPage<KdlGMVo> pageData = kdlGMMapper.getGMList(page, kdlOtherInoutQuery);
//        pageData.convert(x -> {
//            KdlGMVo kdlGmListVo = Convert.convert(KdlGMVo.class, x);
//            return kdlGmListVo;
//        });
        return JsonResult.success(pageData);
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult getFeedbackList(BaseQuery query) {
        KdlGMQuery kdlOtherInoutQuery = (KdlGMQuery) query;
        // 获取数据列表
        IPage<KdlGMVo> page = new Page<>(kdlOtherInoutQuery.getPage(), kdlOtherInoutQuery.getLimit());
        IPage<KdlGMVo> pageData = kdlGMMapper.getGMFeedbackList(page, kdlOtherInoutQuery);
        return JsonResult.success(pageData);
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult updateCompanycode(KdlGM entity) {
        Integer ret= kdlGMMapper.update(new KdlGM(),new UpdateWrapper<KdlGM>().set("companyflag","M").set("ncbatch",entity.getNcbatch()).set("companycode",entity.getCompanycode()).eq("id",entity.getId()));
        return ret>0?JsonResult.success():JsonResult.error();
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public String GetMaxSyncTime() {
        return kdlGMMapper.GetMaxSyncTime();
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public List<KdlGM> getGMSubmitList() {
        return kdlGMMapper.getGMSubmitList();
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult getDetailList(String orderno) {
        return JsonResult.success(kdlGMMapper.getGMDetailList(orderno));
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult getDetailListBySineOrder(String principalorderno) {
        return JsonResult.success(kdlGMMapper.getGMDetailListBySineOrder(principalorderno));
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public boolean updateInoutStep(String orderno,Integer step) {
        UpdateWrapper<KdlGM> updateWrapper = new UpdateWrapper<>();
        //根据单号、事业部、转出库位、转入库位更新回写状态
        updateWrapper.set("inoutstep", step).eq("orderno", orderno);
        //entity.setStatus(Constants.NC_SUBMIT_STATUS);
        return kdlGMMapper.update(new KdlGM(), updateWrapper)==0?true:false;
    }

    @Override
    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public JsonResult syncGM(KdlGMQuery query) {
        try {
            if(StringUtils.isEmpty(query.getStarttime())){
                query.setStarttime(this.GetMaxSyncTime());
            }
            StringBuilder sb = new StringBuilder();
            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sb.append("<CAH3PL>");
            sb.append("<Head>");
            sb.append("<PrincipalID>" + CommonConfig.kdlCompanyId + "</PrincipalID>");
            sb.append("<DocType>GM</DocType>");
            sb.append("<StartTime>" + query.getStarttime() + "</StartTime>");
            sb.append("<EndTime>" + query.getEndtime() + "</EndTime>");
            sb.append("</Head>");
            sb.append("</CAH3PL>");
            DDKJConfig config = new KDLConfig();
            config.setUseSandbox(CommonConfig.kdlSandbox);
            KDLRequest request = null;
            request = new KDLRequest(config);
            String postData = "";
            String result = "";
            NcServiceLog log = new NcServiceLog();
            //String danj_no = dto.body.length>0?dto.body[0].getDanj_no():"";
            String body = sb.toString();
            log.setSubmitNo(query.getPrincipalid()+"_"+query.getDoctype());

            log.setRequestBody(body);
            StringBuilder sbResult = new StringBuilder();
            log.setSubmitTime(DateUtils.now());
            try {
                result = request.postData(CommonConfig.kdlSandbox?SHYPConstants.KDL_GETCONFIRMATION_URL_SUFFIX_TEST: SHYPConstants.KDL_GETCONFIRMATION_URL_SUFFIX, "", null, body, config.getUseSandbox());
                log.setResponseBody(result);
                log.setResponseCode("");
                log.setResponseResult("");
                ncServiceLogService.save(log);
                //result = "<?xml version=\"1.0\" encoding=\"utf-8\"?><CAH3PL><Head><FunCode>9000</FunCode><Remark>读取数据成功</Remark><DocType>GM</DocType></Head><Details><Detail><OrderNo>4911568514</OrderNo><PrincipalOrderNo/><DOCNo>0000000063877638</DOCNo><Ordertype>311</Ordertype><SN>0001</SN><ItemNo>0119020401</ItemNo><BatchNo>0006403221</BatchNo><QTY>5000.000</QTY><Unit>EA</Unit><FromLocation>1012</FromLocation><ToLocation>1001</ToLocation><Plant>T150</Plant><Date>20240130</Date><GmName>吕 天成</GmName><VendorBatch>230132</VendorBatch><BoxFlag>ZX</BoxFlag><BoxNo/></Detail></Details></CAH3PL>";
                Document docResult = XmlUtil.readXML(result);
                Element elementG = XmlUtil.getRootElement(docResult);
                for (int j = 0; j < elementG.getChildNodes().getLength(); j++) {
                    Element elementGR = (Element) elementG.getChildNodes().item(j);
                    Element headResult = XmlUtil.getElement(elementGR, "Head");
                    Element detailResult = XmlUtil.getElement(elementGR, "Details");
                    String resCode = CommonUtils.XmlGetNodeContent(headResult, "FunCode");
                    String resRemark = CommonUtils.XmlGetNodeContent(headResult, "Remark");

                    if ("9000".equals(resCode)) {
                        //解析返回的数据并保存
                        KdlGM kdlGM = new KdlGM();
                        //遍历明细Details
                        Element detail = null;
                        for (int i = 0; i < detailResult.getChildNodes().getLength(); i++) {
                            detail = (Element) detailResult.getChildNodes().item(i);
                            kdlGM.setDoctype(CommonUtils.XmlGetNodeContent(headResult, "DocType"));
                            String pgidate = DateUtil.format(DateUtil.parse(CommonUtils.XmlGetNodeContent(detail, "Time"), DateUtils.YYYY_MM_DD_HH_MM_SS), DateUtils.YYYY_MM_DD);
                            kdlGM.setOrderdate(pgidate);
                            kdlGM.setOrderno(CommonUtils.XmlGetNodeContent(detail, "OrderNo"));
                            kdlGM.setPrincipalorderno(CommonUtils.XmlGetNodeContent(detail, "PrincipalOrderNo"));
                            kdlGM.setDocno(CommonUtils.XmlGetNodeContent(detail, "DOCNo"));
                            kdlGM.setOrdertype(CommonUtils.XmlGetNodeContent(detail, "Ordertype"));
                            kdlGM.setSn(CommonUtils.XmlGetNodeContent(detail, "SN"));
                            kdlGM.setItemno(CommonUtils.XmlGetNodeContent(detail, "ItemNo"));
                            kdlGM.setBatchno(CommonUtils.XmlGetNodeContent(detail, "BatchNo"));
                            kdlGM.setQty(new BigDecimal(CommonUtils.XmlGetNodeContent(detail, "QTY", 0)));
                            kdlGM.setUnit(CommonUtils.XmlGetNodeContent(detail, "Unit"));
                            kdlGM.setFromlocation(CommonUtils.XmlGetNodeContent(detail, "FromLocation"));
                            kdlGM.setTolocation(CommonUtils.XmlGetNodeContent(detail, "ToLocation"));
                            kdlGM.setPlant(CommonUtils.XmlGetNodeContent(detail, "Plant"));
                            kdlGM.setGmname(CommonUtils.XmlGetNodeContent(detail, "GmName"));
                            kdlGM.setVendorbatch(CommonUtils.XmlGetNodeContent(detail, "VendorBatch"));
                            kdlGM.setBoxflag(CommonUtils.XmlGetNodeContent(detail, "BoxFlag"));
                            kdlGM.setBoxno(CommonUtils.XmlGetNodeContent(detail, "BoxNo"));
                            kdlGM.setSyncTime(CommonUtils.XmlGetNodeContent(detail, "Time"));
                            kdlGM.setSapbatch(CommonUtils.XmlGetNodeContent(detail, "SAPbatch"));
                            kdlGM.setBatchnoto(CommonUtils.XmlGetNodeContent(detail, "BatchNoTo"));
                            kdlGM.setBoxflagto(CommonUtils.XmlGetNodeContent(detail, "BoxFlag_TO"));
                            kdlGM.setBoxnoto(CommonUtils.XmlGetNodeContent(detail, "BoxNo_TO"));

                            if (!StringUtils.isEmpty(kdlGM.getPrincipalorderno()) && kdlGM.getPrincipalorderno().startsWith("FK")) {
                                //根据异常反馈单号查找异常反馈对应的事业部
                                KdlQffFeedback qff = kdlQffFeedbackMapper.selectOne(new QueryWrapper<KdlQffFeedback>().eq("principalorderno", kdlGM.getPrincipalorderno()));
                                // 数量和批号对上，更新对应单据那条明细的状态
                                updateOrderStatus(qff, kdlGM);
                            }
                            //根据物料号+批号查找对应的组织，若是未查到组织或是组织有多个，则需要人工干预更新对应的组织
                            if(ncOnhandMapper.getOrgcodeList(kdlGM.getItemno(),kdlGM.getVendorbatch()).size()==1) {
                                String companycode = ncOnhandMapper.getOrgcodeByInvcodeLotno(kdlGM.getItemno(), kdlGM.getVendorbatch());
                                kdlGM.setCompanycode(companycode);
                                //如果是异常反馈过来的数据填充事业部
                            }else if (!StringUtils.isEmpty(kdlGM.getPrincipalorderno()) && kdlGM.getPrincipalorderno().startsWith("FK")){
                                //根据异常反馈单号查找异常反馈对应的事业部
                                KdlQffFeedback qff = kdlQffFeedbackMapper.selectOne(new QueryWrapper<KdlQffFeedback>().eq("principalorderno", kdlGM.getPrincipalorderno()));
                                if(qff!=null) {
                                    kdlGM.setCompanycode(qff.getCompanycode());
                                }else{
                                    kdlGM.setCompanycode("");
                                }
                            }else{
                                kdlGM.setCompanycode("");
                            }
                            List<KdlGM> list1 = kdlGMMapper.selectList(new QueryWrapper<KdlGM>().eq("docno", kdlGM.getDocno()).eq("sn",kdlGM.getSn()));
                            if (list1.size() == 0) {
                                kdlGM.setStatus(Constants.NC_TO_SUBMIT_STATUS);
                                kdlGMMapper.insert(kdlGM);
                            } else {
                                //已回写NC的单据不做更新
                                if(!list1.get(0).getStatus().equals(Constants.NC_SUBMIT_STATUS)) {
                                    //如果是移库异常处理，已经更新过事业部，则忽略更新
                                    if(StringUtils.isNull(list1.get(0).getCompanyflag())){
                                        kdlGM.setId(list1.get(0).getId());
                                        kdlGM.setUpdateTime(DateUtils.now());
                                        kdlGMMapper.updateById(kdlGM);
                                    }else {
                                        if (!list1.get(0).getCompanyflag().toUpperCase().equals("M") || StringUtils.isEmpty(list1.get(0).getCompanycode())) {
                                            kdlGM.setId(list1.get(0).getId());
                                            kdlGM.setUpdateTime(DateUtils.now());
                                            kdlGMMapper.updateById(kdlGM);
                                        }
                                    }
                                }
                            }
                        }

                        //return JsonResult.success(result);
                    } else {
                        sbResult.append(resCode + ":" + resRemark);
                    }
                }
                return StringUtils.isEmpty(sbResult.toString())?JsonResult.success():JsonResult.error(sbResult.toString());

            } catch (Exception ex) {
                log.setResponseBody(ex.getMessage());
                log.setResponseCode("500");
                log.setResponseResult("");
                ncServiceLogService.save(log);
                //return JsonResult.error(StringUtils.isEmpty(result) ? ex.getMessage() : result);
                return JsonResult.error(ex.getMessage());

            }
        }
        catch(Exception ex)
        {
            return JsonResult.error(ex.getMessage());
        }
    }

    @SpecifyDataSource(value = DataSourceType.SINESYS)
    public void updateOrderStatus(KdlQffFeedback qff, KdlGM kdlGM) {
        try {
            String orderno = qff.getOrderno();
            //销退过来的qff移库
            if (orderno.contains("SO")) {
                KdlZ05kdl kdlZ05 = z05kdlMapper.selectOne(new QueryWrapper<KdlZ05kdl>().eq("vendorso", orderno));
                String fromlocation = kdlGM.getFromlocation();
                //待验库 检查 销退对应明细行的那条数据，物料、批号、数量、仓位是否匹配
                if ("1012".equals(fromlocation)) {
                    List<KdlZ05kdlB> kdlZ05bs = z05kdlBMapper.selectList(new QueryWrapper<KdlZ05kdlB>()
                            .eq("pid", kdlZ05.getId()).eq("materialcode", kdlGM.getItemno()).eq("vendorbatch", kdlGM.getVendorbatch())
                            .eq("quarantineqty", kdlGM.getQty())
                            .gt("quarantineqty", 0));
                    if (!CollectionUtils.isEmpty(kdlZ05bs) && kdlZ05bs.size() == 1) {
                        KdlZ05kdlB z05kdlb = kdlZ05bs.get(0);
                        //更新回写状态
                        DynamicDataSource.setDataSource("sinesys");
                        KdlInspectionresultStatus inspectionresultStatus = new KdlInspectionresultStatus();
                        inspectionresultStatus.setCwarehouseid(fromlocation);
                        inspectionresultStatus.setInspectionlot(z05kdlb.getInspectionlot());
                        inspectionresultStatus.setStatus(Constants.NC_SUBMIT_STATUS);
                        List<KdlInspectionresultStatus> list = kdlInspectionresultStatusMapper.selectList(new QueryWrapper<KdlInspectionresultStatus>().eq("inspectionlot", z05kdlb.getInspectionlot()).eq("cwarehouseid", fromlocation));
                        if (CollectionUtils.isEmpty(list)) {
                            kdlInspectionresultStatusMapper.insert(inspectionresultStatus);
                        }
                    }
                }
            }
        } catch (Exception e) {
        }
    }

    /**
     * 获取详情Vo
     *
     * @param id 记录ID
     * @return
     */
    @Override
    public Object getInfo(Serializable id) {
        KdlGM entity = (KdlGM) super.getInfo(id);
        // 返回视图Vo
        KdlOtherInoutInfoVo kdlOtherInoutInfoVo = new KdlOtherInoutInfoVo();
        // 拷贝属性
        BeanUtils.copyProperties(entity, kdlOtherInoutInfoVo);
        return kdlOtherInoutInfoVo;
    }

    /**
     * 添加、更新记录
     *
     * @param entity 实体对象
     * @return
     */
    @Override
    public JsonResult edit(KdlGM entity) {
        if (StringUtils.isNotNull(entity.getId()) && entity.getId() > 0) {
        } else {
        }
        return super.edit(entity);
    }

    /**
     * 删除记录
     *
     * @param entity 实体对象
     * @return
     */
    @Override
    public JsonResult delete(KdlGM entity) {
        entity.setMark(0);
        return super.delete(entity);
    }

}